using System;
using System.Collections.Generic;

namespace LannyPractiseCode.Shu
{
    public class MyHeroNode2
    {
        public int Id { set; get; }
        public string Name { get; set; }
        public MyHeroNode2 Left { set; get; }
        public MyHeroNode2 Right { set; get; }

        //说明
        //1.如果leftType == 0表示指向的是左子树，如果1则表示指向前驱结点
        //2.如果rightType == 0表示指向是右子树，如果1表示指向后继结点

        public int leftType{set;get;}
        public int rightType{set;get;}

        public MyHeroNode2(int id, string name)
        {
            this.Id = id;
            this.Name = name;
        }

        public override string ToString()
        {
            return "HeroNode no=" + Id + ",name=" + Name;
        }

        //前序遍历
        public void PreOrder()
        {
            System.Console.WriteLine(this);
            //递归向左子树遍历
            if (this.Left != null)
                this.Left.PreOrder();

            //递归向右子树遍历
            if (this.Right != null)
                this.Right.PreOrder();
        }

        //中序遍历
        public void InFixOrder()
        {
            if (this.Left != null)
                this.Left.InFixOrder();

            System.Console.WriteLine(this);

            if (this.Right != null)
                this.Right.InFixOrder();
        }

        //后续遍历
        public void PostOrder()
        {
            if (this.Left != null)
                this.Left.InFixOrder();


            if (this.Right != null)
                this.Right.InFixOrder();

            System.Console.WriteLine(this);

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="No">查找的Id</param>
        /// <returns></returns>
        public MyHeroNode2 PreOrderSearch(int No)
        {
            //比较当前节点是不是
            if (this.Id == No)
                return this;

            //1.则判断当前结点的左子节点是否为空，如果不为空，则递归前序查找
            //2.如果左递归前序查找，找到结点，则返回
            MyHeroNode2 resNode = null;
            if (this.Left != null)
                resNode = this.Left.PreOrderSearch(No);

            if (resNode != null)
                return resNode;

            //1.左递归前序查找，找到结点，则返回,否继续判断，
            //2.当前的结点的右子节点是否为空，如果不空,则继续向右递归前序查找
            if (this.Right != null)
                resNode = this.Right.PreOrderSearch(No);

            return resNode;
        }

        //中序查找
        public MyHeroNode2 InFixOrderSearch(int no)
        {
            MyHeroNode2 resNode = null;
            if (this.Left != null)
                resNode = this.Left.InFixOrderSearch(no);

            if (resNode != null)
                return resNode;

            if (this.Id == no)
                return this;

            if (this.Right != null)
                resNode = this.Right.InFixOrderSearch(no);

            return resNode;
        }

        //后续遍历查找。。
        public MyHeroNode2 PostOrderSerach(int no)
        {
            //判断当前结点的左子节点是否为空，如果不为空，则递归后序查找
            MyHeroNode2 resNode = null;
            if (this.Left != null)
                resNode = this.Left.PostOrderSerach(no);

            if (resNode != null)//说明在左子树找到
                return resNode;

            if (this.Right != null)
                resNode = this.Right.PostOrderSerach(no);

            if (resNode != null) ////说明在右子树找到
                return resNode;

            if(this.Id==no)
                return this;
            else
                return resNode;
        }

        //删除
        public void DeleNode(int no)
        {
            //如果当前结点的左子结点不为空，并且左子结点就是要删除结点，就将this.left = nu1l; 并且就返回(结束递归删除)
            if(this.Left!=null && this.Left.Id==no)
            {
                this.Left=null;
                return;
            }
            //3.如果当前结点的右子结点不为空，并且右子结点就是要删除结点，就将this.right= nu1l ;并且就返回(结束递归删除)
            if(this.Right!=null && this.Right.Id==no)
            {
                this.Right=null;
                return;
            }
            //向左子树递归删除
            if(this.Left!=null)
                this.Left.DeleNode(no);

            //向右子树进行递归删除
            if(this.Right!=null)
                this.Right.DeleNode(no);

        }
    }
}